package cn.nzcong.jpress.addon.articlesync.controller;

import cn.nzcong.jpress.addon.articlesync.annotation.SecondStep;
import cn.nzcong.jpress.addon.articlesync.common.Exception.AuthException;
import cn.nzcong.jpress.addon.articlesync.common.Exception.BaseException;
import cn.nzcong.jpress.addon.articlesync.common.Exception.InvalidParamException;
import cn.nzcong.jpress.addon.articlesync.common.GoogleAuthenticator;
import cn.nzcong.jpress.addon.articlesync.common.SecondStepAuthHelper;
import cn.nzcong.jpress.addon.articlesync.service.impl.ConfigOptionService;
import cn.nzcong.jpress.addon.articlesync.vo.config.SecondStepConfig;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import io.jboot.utils.RequestUtil;
import io.jboot.web.controller.annotation.RequestMapping;
import io.jpress.web.base.AdminControllerBase;
import io.jpress.web.interceptor.AdminInterceptor;
import io.jpress.web.interceptor.CSRFInterceptor;
import io.jpress.web.interceptor.PermissionInterceptor;
import io.jpress.web.interceptor.UserInterceptor;
import org.apache.commons.lang3.StringUtils;

@RequestMapping(value = "/admin/articlesync/ssa",viewPath = "/")
@Before({
        CSRFInterceptor.class,
        AdminInterceptor.class,
        UserInterceptor.class,
        PermissionInterceptor.class,
})
public class ArticleSyncSsaController extends AdminControllerBase {

    @Inject
    private ConfigOptionService configOptionService;

    public void secondStep(){
        render("articlesync/secondStep.html");
    }

    @SecondStep
    public void doSetSSAuth(Boolean enable, String key, String code){
        try{
            if(!StringUtils.isNumeric(code)){
                throw new InvalidParamException("请输入正确的验证码");
            }
            long codeLong = Long.valueOf(code);
            enable = enable != null && enable;
            key = enable ? key : configOptionService.getSecondStepConfig().getKey();
            if(StringUtils.isBlank(key) || codeLong < 100000 || codeLong > 999999){
                throw new InvalidParamException("参数错误");
            }
            if(!GoogleAuthenticator.getInstance().check_code(key, codeLong, System.currentTimeMillis())){
                throw new InvalidParamException("验证码无效");
            }
            SecondStepConfig ssConf = new SecondStepConfig();
            ssConf.setEnable(enable);
            ssConf.setKey(key);
            configOptionService.saveSecondStepConfig(ssConf);
            // set Cookie
            if(enable){
                SecondStepAuthHelper.setCookie(super.getResponse(), ssConf.getKey());
            }
            renderJson(Ret.ok("message", "验证通过"));
        } catch (BaseException e){
            renderJson(Ret.fail("message", "验证失败 - " + e.getMessage()));
        } catch (Throwable e){
            renderJson(Ret.fail("message", "内部错误 - " + e.getMessage()));
        }
    }

    public void doSSAuth(Long code, String redirect){
        try{
            if(code == null){
                throw new InvalidParamException("验证失败，请输入正确的code");
            }
            SecondStepConfig ssConf = configOptionService.getSecondStepConfig();
            if(!ssConf.isEnable()){
                throw new AuthException("两步验证未开启");
            }
            if(!GoogleAuthenticator.getInstance().check_code(ssConf.getKey(), code, System.currentTimeMillis())){
                throw new AuthException("验证失败");
            }
            // setCookie
            SecondStepAuthHelper.setCookie(super.getResponse(), ssConf.getKey());
            renderJson(Ret.ok("message", "验证通过"));

            if(RequestUtil.isAjaxRequest(super.getRequest())){
                renderJavascript("window.history.go(-1)");
            } else {
                super.forwardAction(redirect);
            }
        } catch (BaseException e){
            renderJson(Ret.fail("message", e.getMessage()));
        } catch (Throwable e){
            renderJson(Ret.fail("message", "内部错误 - " + e.getMessage()));
        }
    }

    public void ssaRndCode(){
        try{
            // 生成随机key
            String key = GoogleAuthenticator.generateSecretKey();
            // 拼装小程序码
            String qrCodeKey = GoogleAuthenticator.getQRBarcodeText(getLoginedUser().getUsername(), getAttrForStr("domain"), key);
            JSONObject ssaObj = new JSONObject();
            ssaObj.put("ssaKey", key);
            ssaObj.put("qrCode", qrCodeKey);
            renderJson(ssaObj);
            renderJson(Ret.ok("ssaObj", ssaObj));
        } catch (BaseException e){
            renderJson(Ret.fail("message", e.getMessage()));
        } catch (Throwable e){
            renderJson(Ret.fail("message", "内部错误 - " + e.getMessage()));
        }
    }
}
